// SerializationTest.cpp : Defines the entry point for the console application.
//

//#include <crtdbg.h>


//#ifdef _DEBUG
//void* operator new(size_t nSize, const char * lpszFileName, int nLine)
//{
//    return ::operator new(nSize, 1, lpszFileName, nLine);
//}
//#define DEBUG_NEW new(THIS_FILE, __LINE__)
//
//#define MALLOC_DBG(x) _malloc_dbg(x, 1, THIS_FILE, __LINE__);
//#define malloc(x) MALLOC_DBG(x)
//
//#endif // _DEBUG


//#if defined(_DEBUG) && defined(_MSC_VER) && !defined(new)
//#undef new
//#define _CRTDBG_MAP_ALLOC
//#include <stdlib.h>
//#include <crtdbg.h>
//#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
//#endif


//
//#define _CRTDBG_MAP_ALLOC
//#include <stdlib.h>
//#include <crtdbg.h>

//#ifdef _CRTDBG_MAP_ALLOC
//  inline void* __cdecl operator new(unsigned int s)
//     { return ::operator new(s, _NORMAL_BLOCK, __FILE__, __LINE__); }
//  #endif 

//#ifdef  _CRTDBG_MAP_ALLOC
//#define   malloc(s)             _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
//// etc...
//#endif



#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <boost/test/minimal.hpp>
#include <boost/asio/streambuf.hpp>

#include "Libs/Native/Messages/Message.P2.OrderStateChanged.h"
#include "Libs/Native/Messages/Message.P2.QuotesDump.h"
#include "Libs/Native/Messages/Message.P2.AddOrder.h"
#include "Libs/Native/Messages/Message.P2.CancelOrder.h"
#include "Libs/Native/Messages/Message.P2.GetQuotes.h"

using namespace AlgoTrading::Messages;

void SerializeOrderStateChanged(std::ostream& stream)
{
	std::auto_ptr<P2OrderStateChanged> object(new P2OrderStateChanged());
	object->SetAmountRest(99);
	object->SetOrderState(P2OrderStateChanged::ORDER_STATE_CANCELLED);
	object->Serialize(stream);
}

void DeserializeOrderStateChanged(std::istream& stream)
{
	std::auto_ptr<ServerMessage> mes  = ServerMessage::Deserialize(stream);

	BOOST_REQUIRE(mes->GetServerMessageType() == ServerMessage::NOTIFICATION_MESSAGE);
	NotificationMessage* notificationMessage = static_cast<NotificationMessage*>(mes.get());
	BOOST_REQUIRE(notificationMessage->GetNotificationMessageType() == NotificationMessage::ORDER_STATE_CHANGED);

	P2OrderStateChanged* object = static_cast<P2OrderStateChanged*>(mes.get());

	BOOST_REQUIRE(object->GetAmountRest() == 99);
	BOOST_REQUIRE(object->GetOrderState() == P2OrderStateChanged::ORDER_STATE_CANCELLED);
}


void SerializeQuotesDump(std::iostream& stream)
{
	std::auto_ptr<P2QuotesDump> object(new P2QuotesDump());
	object->SetRequestId(100);
	for(int i =0; i < 100; ++i)
	{
		object->PushQuote(i);
	}
	object->Serialize(stream);
}

void DeserializeQuotesDump(std::iostream& stream)
{
	std::auto_ptr<ServerMessage> mes  = ServerMessage::Deserialize(stream);

	BOOST_REQUIRE(mes->GetServerMessageType() == ServerMessage::REQUEST_RESPONSE);
	RequestResponse* requestResponse = static_cast<RequestResponse*>(mes.get());
	BOOST_REQUIRE(requestResponse->GetRequestResponseMessageType() == RequestResponse::QUOTES_DUMP);



	P2QuotesDump* object = static_cast<P2QuotesDump*>(mes.get());

	BOOST_REQUIRE(object->GetRequestId() == 100);
	BOOST_REQUIRE(object->GetQuotesSize() == 100);
	for(int i =0 ; i < 100; ++i)
	{
		BOOST_REQUIRE(object->GetQuote(i) == i);
	}
}

void SerializeAddOrder(std::iostream& stream)
{
	std::auto_ptr<P2AddOrder> object(new P2AddOrder());
	object->SetOrderAmount(99);
	object->SetOrderPrice(99.5);
	object->SetOrderType(P2AddOrder::ORDER_TYPE_BID);
	object->SetOrderUniqueId(std::string("superTest"));
	object->SetSequrity(std::string("testSecurity"));
	object->Serialize(stream);
}

void DeserializeAddOrder(std::iostream& stream)
{
	std::auto_ptr<ClientMessage> mes  = ClientMessage::Deserialize(stream);

	BOOST_REQUIRE(mes->GetClientMessageType() == ClientMessage::REQUEST_WITHOUT_RESPONSE);
	RequestWithoutResponse* requestWithoutResponse = static_cast<RequestWithoutResponse*>(mes.get());
	BOOST_REQUIRE(requestWithoutResponse->GetRequestWithoutResponseMessageType() == RequestWithoutResponse::ADD_ORDER);

	P2AddOrder* object = static_cast<P2AddOrder*>(mes.get());

	BOOST_REQUIRE(object->GetOrderAmount() == 99);
	BOOST_REQUIRE(object->GetOrderPrice() == 99.5);
	BOOST_REQUIRE(object->GetOrderType() == P2AddOrder::ORDER_TYPE_BID);
	BOOST_REQUIRE(object->GetOrderUniqueId() == std::string("superTest"));
	BOOST_REQUIRE(object->GetSequrity() == std::string("testSecurity"));
}

void SerializeCancelOrder(std::iostream& stream)
{
	std::auto_ptr<P2CancelOrder> object(new P2CancelOrder());
	object->SetOrderUniqueId(std::string("superTest"));
	object->Serialize(stream);
}

void DeserializeCancelOrder(std::iostream& stream)
{
	std::auto_ptr<ClientMessage> mes  = ClientMessage::Deserialize(stream);

	BOOST_REQUIRE(mes->GetClientMessageType() == ClientMessage::REQUEST_WITHOUT_RESPONSE);
	RequestWithoutResponse* requestWithoutResponse = static_cast<RequestWithoutResponse*>(mes.get());
	BOOST_REQUIRE(requestWithoutResponse->GetRequestWithoutResponseMessageType() == RequestWithoutResponse::CANCEL_ORDER);

	P2CancelOrder* object = static_cast<P2CancelOrder*>(mes.get());

	BOOST_REQUIRE(object->GetOrderUniqueId() == std::string("superTest"));
}

void SerializeGetQuotes(std::iostream& stream)
{
	std::auto_ptr<P2GetQuotes> object(new P2GetQuotes());
	object->SetSequrityId(99);
	object->SetRequestId(98);
	object->Serialize(stream);
}

void DeserializeGetQuotes(std::iostream& stream)
{
	std::auto_ptr<ClientMessage> mes  = ClientMessage::Deserialize(stream);

	BOOST_REQUIRE(mes->GetClientMessageType() == ClientMessage::REQUEST_WITH_RESPONSE);
	RequestWithResponse* requestWithResponse = static_cast<RequestWithResponse*>(mes.get());
	BOOST_REQUIRE(requestWithResponse->GetRequestWithResponseMessageType() == RequestWithResponse::GET_QUOTES);

	P2GetQuotes* object = static_cast<P2GetQuotes*>(mes.get());

	BOOST_REQUIRE(object->GetSequrityId() == 99);
	BOOST_REQUIRE(object->GetRequestId() == 98);
}

int test_main( int argc,  char * argv[])
{
	boost::asio::streambuf sb;
	std::ostream os(&sb);
	SerializeOrderStateChanged(os);

	{
	//int* a = new int;

	std::stringstream stream(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
	
	SerializeOrderStateChanged(stream);
	DeserializeOrderStateChanged(stream);
	stream.clear();

	SerializeQuotesDump(stream);
	DeserializeQuotesDump(stream);
	stream.clear();

	SerializeAddOrder(stream);
	DeserializeAddOrder(stream);
	stream.clear();

	SerializeCancelOrder(stream);
	DeserializeCancelOrder(stream);
	stream.clear();

	SerializeGetQuotes(stream);
	DeserializeGetQuotes(stream);
	stream.clear();
	}

	::google::protobuf::ShutdownProtobufLibrary();

	//_CrtDumpMemoryLeaks();

	return 0;
}

